/**
         * 短视频播放器（Node.js服务器版本）
         */
class ShortVideoPlayer {
    constructor() {
        // DOM元素
        this.elements = {
            currentVideo: document.getElementById('currentVideo'),
            videoContainer: document.getElementById('videoContainer'),
            backgroundImage: document.getElementById('backgroundImage'),
            loadingIndicator: document.getElementById('loadingIndicator'),
            errorMessage: document.getElementById('errorMessage'),
            playOverlay: document.getElementById('playOverlay'),
            playIcon: document.getElementById('playIcon'),
            muteIcon: document.getElementById('muteIcon'),
            swipeHint: document.getElementById('swipeHint'),
            historyHint: document.getElementById('historyHint'),
            keyboardHint: document.getElementById('keyboardHint'),
            indexUpdateHint: document.getElementById('indexUpdateHint'),
            serverStatus: document.getElementById('serverStatus'),
            statusText: document.getElementById('statusText'),
            playModeIndicator: document.getElementById('playModeIndicator'), // 播放模式显示元素
            progressContainer: document.getElementById('progressContainer'),
            progressBar: document.getElementById('progressBar'),
            progressHandle: document.getElementById('progressHandle')
        };

        // 配置参数 - 默认值
        this.config = {
            apiBaseUrl: '',
            defaultVolume: 0.7,
            swipeThreshold: 50,
            swipeTimeThreshold: 500,
            // 防抖延迟（毫秒）
            debounceDelay: 300,
            // 视频切换最小间隔（毫秒）
            minSwitchInterval: 800,
            // 滚落延迟（毫秒）
            rollDelay: 500,
            // 快进快退初始时间（秒）
            seekStep: 3,
            // 快进快退最大时间（秒）
            maxSeekStep: 10,
            // 连续按键加速阈值（毫秒）
            seekAccelerationThreshold: 300
        };

        // 状态管理
        this.state = {
            videoList: [],
            playHistory: [],
            currentIndex: -1,
            isLoading: false,
            startY: 0,
            startTime: 0,
            isMuted: true,
            touchCount: 0,
            lastTouchTime: 0,
            serverConnected: false,
            // 播放模式：'random' 表示随机播放，'loop' 表示单视频循环
            playMode: 'random',
            // 防抖相关状态
            lastScrollTime: 0,
            pendingVideoRequest: null,
            currentVideoAbortController: null,
            // 滚落机制相关状态
            lastVideoSwitchTime: 0,
            isRolling: false,
            rollTimeout: null,
            // 快进快退相关状态
            lastSeekTime: 0,
            currentSeekStep: this.config.seekStep,
            // 进度条拖拽状态
            isDragging: false
        };

        // 窗口大小调整防抖定时器
        this.resizeTimer = null;

        // 初始化
        this.init();
    }

    /**
     * 初始化函数
     */
    async init() {
        try {
            // 检查服务器连接
            await this.checkServerConnection();

            // 获取服务器配置
            await this.loadServerConfig();

            // 加载视频索引
            await this.loadVideoIndex();

            // 设置事件监听
            this.setupEventListeners();

            // 显示键盘提示
            // 默认显示键盘提示，用户可以通过H键控制显示/隐藏
            this.elements.keyboardHint.classList.remove('hidden');

            // 隐藏滑动提示
            this.hideSwipeHint();

            // 添加重试按钮事件监听器
            const retryButton = document.getElementById('retryButton');
            if (retryButton) {
                retryButton.addEventListener('click', async () => {
                    this.hideError();
                    this.showLoading();
                    // 使用refreshVideoIndex而不是loadVideoIndex来确保索引被重新生成
                    await this.refreshVideoIndex();
                });
            }

            console.log('短视频播放器初始化完成');
        } catch (error) {
            console.error('初始化失败:', error);
            this.showError('初始化失败，请检查服务器连接');
        }
    }

    /**
     * 检查服务器连接
     */
    async checkServerConnection() {
        try {
            const response = await fetch('/api/status');
            if (response.ok) {
                const status = await response.json();
                this.state.serverConnected = status.status === 'running';
                this.updateServerStatus(true);
                console.log('服务器连接成功:', status);
            } else {
                this.state.serverConnected = false;
                this.updateServerStatus(false);
                console.warn('服务器连接失败');
            }
        } catch (error) {
            this.state.serverConnected = false;
            this.updateServerStatus(false);
            console.error('服务器连接检查失败:', error);
        }
    }

    /**
     * 从服务器加载配置
     */
    async loadServerConfig() {
        try {
            const response = await fetch('/api/config');
            if (response.ok) {
                const serverConfig = await response.json();
                
                // 更新播放器配置
                this.config.minSwitchInterval = serverConfig.player.min_switch_interval || this.config.minSwitchInterval;
                this.config.swipeThreshold = serverConfig.player.swipe_threshold || this.config.swipeThreshold;
                this.config.swipeTimeThreshold = serverConfig.player.swipe_time_threshold || this.config.swipeTimeThreshold;
                this.config.rollDelay = serverConfig.player.roll_delay || this.config.rollDelay;
                this.config.seekStep = serverConfig.player.seek_step || this.config.seekStep;
                this.config.maxSeekStep = serverConfig.player.max_seek_step || this.config.maxSeekStep;
                this.config.seekAccelerationThreshold = serverConfig.player.seek_acceleration_threshold || this.config.seekAccelerationThreshold;
                
                console.log('成功加载服务器配置:', serverConfig);
            } else {
                console.warn('获取服务器配置失败，使用默认配置');
            }
        } catch (error) {
            console.error('加载服务器配置失败:', error);
            console.warn('使用默认配置');
        }
    }

    /**
     * 更新服务器状态显示
     */
    updateServerStatus(connected) {
        if (connected) {
            this.elements.serverStatus.innerHTML = '<i class="fa fa-circle text-green-400 animate-pulse"></i> 已连接';
            this.elements.statusText.textContent = '已连接';
        } else {
            this.elements.serverStatus.innerHTML = '<i class="fa fa-circle text-red-400 animate-pulse"></i> 未连接';
            this.elements.statusText.textContent = '未连接';
        }
    }

    /**
     * 加载视频索引
     */
    async loadVideoIndex() {
        try {
            this.showLoading();

            const response = await fetch('/api/videos');
            if (!response.ok) {
                throw new Error('获取视频列表失败');
            }

            this.state.videoList = await response.json();
            console.log('成功加载视频索引，共', this.state.videoList.length, '个视频');

            // 在加载索引后立即生成随机播放列表
            this.initializePlayHistory();

            // 如果有视频，预加载第一个视频但不立即播放
            if (this.state.videoList.length > 0) {
                await this.prefetchFirstVideo();
            } else {
                this.hideLoading();
                this.showError('没有找到视频文件，请添加视频到videos目录');
            }

        } catch (error) {
            console.error('加载索引失败:', error);
            this.hideLoading();
            this.showError('加载视频列表失败');
        }
    }

    /**
     * 刷新视频索引
     */
    async refreshVideoIndex() {
        try {
            this.showLoading();

            const response = await fetch('/api/update-index', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                }
            });

            if (!response.ok) {
                throw new Error('更新索引请求失败');
            }

            const result = await response.json();
            console.log('索引更新成功:', result);

            // 重新加载索引
            await this.loadVideoIndex();

            // 显示成功提示
            this.showIndexUpdateSuccess();

        } catch (error) {
            console.error('刷新索引失败:', error);
            this.showError('更新索引失败');
        } finally {
            this.hideLoading();
        }
    }

    /**
     * 设置事件监听器
     */
    setupEventListeners() {
        // 触摸事件
        this.elements.videoContainer.addEventListener('touchstart', (e) => this.handleTouchStart(e));
        this.elements.videoContainer.addEventListener('touchend', (e) => this.handleTouchEnd(e));

        // 鼠标滚轮事件（PC端）
        this.elements.videoContainer.addEventListener('wheel', (e) => this.handleWheel(e));

        // 点击播放/暂停
        this.elements.videoContainer.addEventListener('click', (e) => {
            if (!e.target.closest('button')) {
                this.togglePlay();
            }
        });



        // 键盘事件
        document.addEventListener('keydown', (e) => this.handleKeyDown(e));

        // 视频事件
        this.elements.currentVideo.addEventListener('ended', () => {
            if (this.state.playMode === 'loop') {
                // 单视频循环模式，重新播放当前视频
                this.elements.currentVideo.currentTime = 0;
                this.elements.currentVideo.play();
            } else {
                // 随机播放模式
                this.playRandomVideo();
            }
        });
        this.elements.currentVideo.addEventListener('error', () => this.handleVideoError());
        this.elements.currentVideo.addEventListener('loadeddata', () => this.onVideoLoaded());
        this.elements.currentVideo.addEventListener('waiting', () => this.showLoading());
        this.elements.currentVideo.addEventListener('playing', () => this.hideLoading());
        this.elements.currentVideo.addEventListener('timeupdate', () => this.updateProgress());
        // 视频元数据加载完成事件，用于调整容器尺寸
        this.elements.currentVideo.addEventListener('loadedmetadata', () => {
            // 添加延迟以确保在页面加载时也能正确调整尺寸
            setTimeout(() => this.adjustContainerForVideo(), 50);
        });

        // 进度条事件
        this.elements.progressContainer.addEventListener('click', (e) => this.handleProgressClick(e));
        this.elements.progressContainer.addEventListener('mousedown', (e) => this.handleProgressDragStart(e));
        document.addEventListener('mousemove', (e) => this.handleProgressDrag(e));
        document.addEventListener('mouseup', (e) => this.handleProgressDragEnd(e));
        // 移动端触摸事件
        this.elements.progressContainer.addEventListener('touchstart', (e) => this.handleProgressTouchStart(e));
        document.addEventListener('touchmove', (e) => this.handleProgressTouchMove(e));
        document.addEventListener('touchend', (e) => this.handleProgressTouchEnd(e));
        
        // 鼠标悬停事件 - 在底部区域显示进度条
        const videoContainer = document.querySelector('.video-container');
        let hoverTimeout;
        
        videoContainer.addEventListener('mousemove', (e) => {
            const rect = videoContainer.getBoundingClientRect();
            const isNearBottom = e.clientY >= rect.bottom - 30; // 底部30px区域内
            
            if (isNearBottom) {
                this.elements.progressContainer.classList.add('show');
                clearTimeout(hoverTimeout);
            } else {
                // 延迟隐藏进度条，避免频繁切换
                hoverTimeout = setTimeout(() => {
                    if (!this.state.isDragging) {
                        this.elements.progressContainer.classList.remove('show');
                    }
                }, 1000);
            }
        });
        
        // 鼠标离开视频容器时隐藏进度条
        videoContainer.addEventListener('mouseleave', () => {
            if (!this.state.isDragging) {
                this.elements.progressContainer.classList.remove('show');
            }
        });
        
        // 添加初始刷新按钮事件监听器
        const initialRetryButton = document.getElementById('initialRetryButton');
        if (initialRetryButton) {
            initialRetryButton.addEventListener('click', async () => {
                await this.refreshVideoIndex();
            });
        }
        
        // 全屏变化事件监听
        document.addEventListener('fullscreenchange', () => this.handleFullscreenChange());
        
        // 窗口大小变化事件监听
        window.addEventListener('resize', () => {
            // 防抖处理，避免频繁调整
            clearTimeout(this.resizeTimer);
            this.resizeTimer = setTimeout(() => {
                this.adjustContainerForVideo();
            }, 100);
        });

        // 定期检查服务器连接
        setInterval(() => this.checkServerConnection(), 30000);
    }

    /**
     * 处理视频加载完成
     */
    onVideoLoaded() {
        this.hideLoading();
    }

    /**
     * Fisher-Yates洗牌算法实现
     * @param {Array} array - 需要洗牌的数组
     * @returns {Array} 洗牌后的数组
     */
    fisherYatesShuffle(array) {
        const shuffled = [...array]; // 创建副本以避免修改原数组
        for (let i = shuffled.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
        }
        return shuffled;
    }

    /**
     * 初始化播放历史，使用Fisher-Yates算法生成随机播放序列
     */
    initializePlayHistory() {
        // 创建一个包含所有视频索引的数组
        const indices = Array.from({ length: this.state.videoList.length }, (_, i) => i);
        // 使用Fisher-Yates算法打乱索引数组
        this.state.shuffledIndices = this.fisherYatesShuffle(indices);
        this.state.currentShuffledIndex = 0;
    }

    /**
     * 预加载第一个视频
     */
    async prefetchFirstVideo() {
        return new Promise((resolve) => {
            // 获取第一个随机视频索引
            const firstIndex = this.state.shuffledIndices[0];
            const firstVideo = this.state.videoList[firstIndex];
            
            if (firstVideo && firstVideo.url) {
                // 创建预加载视频元素
                const preloadVideo = document.createElement('video');
                preloadVideo.preload = 'auto';
                preloadVideo.src = firstVideo.url;
                
                // 当视频可以播放时，隐藏加载指示器并显示播放器
                preloadVideo.addEventListener('canplay', () => {
                    // 隐藏背景图和加载指示器
                    this.elements.backgroundImage.style.display = 'none';
                    this.hideLoading();
                    
                    // 设置当前视频源但不自动播放
                    this.elements.currentVideo.src = firstVideo.url;
                    this.elements.currentVideo.muted = this.state.isMuted;
                    this.elements.currentVideo.volume = this.config.defaultVolume;
                    
                    // 记录当前索引
                    this.state.currentIndex = firstIndex;
                    
                    // 预加载下一个视频
                    this.prefetchNextVideo();
                    
                    resolve();
                });
                
                // 处理预加载错误
                preloadVideo.addEventListener('error', () => {
                    console.error('预加载第一个视频失败');
                    this.hideLoading();
                    resolve();
                });
                
                // 设置超时，避免无限等待
                setTimeout(() => {
                    this.hideLoading();
                    resolve();
                }, 5000); // 5秒超时
            } else {
                this.hideLoading();
                resolve();
            }
        });
    }

    /**
     * 播放指定视频
     */
    async playVideo(index) {
        if (index < 0 || index >= this.state.videoList.length) {
            this.showError('视频索引无效');
            return;
        }

        const video = this.state.videoList[index];

        try {
            this.showLoading();
            this.hideError();

            // 如果存在之前的 AbortController，先中止之前的请求
            if (this.state.currentVideoAbortController) {
                this.state.currentVideoAbortController.abort();
            }

            // 清理之前的视频资源
            this.cleanupPreviousVideo();

            // 创建新的 AbortController
            this.state.currentVideoAbortController = new AbortController();
            const signal = this.state.currentVideoAbortController.signal;

            // 更新视频信息显示


            // 设置视频源
            this.elements.currentVideo.src = video.url;
            this.elements.currentVideo.muted = this.state.isMuted;
            this.elements.currentVideo.volume = this.config.defaultVolume;

            // 记录当前索引
            this.state.currentIndex = index;

            // 预加载下一个视频
            this.prefetchNextVideo();

            // 尝试加载视频，使用重试机制
            await this.loadVideoWithTimeout(signal, 3);

            // 检查请求是否已被中止
            if (signal.aborted) {
                throw new Error('视频加载被中止');
            }

            // 隐藏加载指示器
            this.hideLoading();

            // 不再需要添加到播放历史，因为我们直接在随机数组中前后移动

        } catch (error) {
            if (error.name === 'AbortError') {
                console.log('视频加载被用户中止');
            } else {
                console.error('播放视频失败:', error);
                this.showError('视频播放失败');
                this.hideLoading();
            }
        }
    }

    /**
     * 随机播放下一个视频
     */
    async playRandomVideo() {
        if (this.state.videoList.length === 0) {
            this.showError('没有可用的视频');
            return;
        }

        // 获取下一个随机视频索引
        const newIndex = this.state.shuffledIndices[this.state.currentShuffledIndex];
        
        // 更新索引计数器
        this.state.currentShuffledIndex++;

        // 如果已经播放完所有视频，则重新初始化播放历史
        if (this.state.currentShuffledIndex >= this.state.shuffledIndices.length) {
            this.initializePlayHistory();
        }

        await this.playVideo(newIndex);
    }

    /**
     * 播放上一个视频
     */
    async playPreviousVideo() {
        // 如果当前索引已经是第一个，则无法播放上一个视频
        if (this.state.currentShuffledIndex <= 1) {
            // 显示历史提示
            this.showHistoryHint();
            return;
        }

        // 将当前索引回退两位（一位是当前播放的视频，再一位是上一个视频）
        this.state.currentShuffledIndex -= 2;
        
        // 获取上一个随机视频索引
        const prevIndex = this.state.shuffledIndices[this.state.currentShuffledIndex];
        
        // 更新索引计数器（向前一位）
        this.state.currentShuffledIndex++;
        
        await this.playVideo(prevIndex);
    }

    /**
     * 显示索引更新成功提示
     */
    showIndexUpdateSuccess() {
        // 使用淡入效果显示索引更新提示
        this.elements.indexUpdateHint.classList.remove('hidden', 'fade-out');
        this.elements.indexUpdateHint.classList.add('fade-in');
        
        // 3秒后使用淡出效果隐藏提示
        setTimeout(() => {
            this.elements.indexUpdateHint.classList.remove('fade-in');
            this.elements.indexUpdateHint.classList.add('fade-out');
            
            // 确保动画完成后完全隐藏
            setTimeout(() => {
                this.elements.indexUpdateHint.classList.add('hidden');
            }, 300);
        }, 3000);
    }

    handleTouchStart(e) {
        this.state.startY = e.touches[0].clientY;
        this.state.startTime = Date.now();
        this.state.touchCount++;

        // 双击放大
        if (this.state.touchCount === 2 && Date.now() - this.state.lastTouchTime < 300) {
            this.toggleFullscreen();
            this.state.touchCount = 0;
        }
        this.state.lastTouchTime = Date.now();
    }

    handleTouchEnd(e) {
        const endY = e.changedTouches[0].clientY;
        const endTime = Date.now();
        const deltaY = this.state.startY - endY;
        const deltaTime = endTime - this.state.startTime;

        // 重置触摸计数
        setTimeout(() => {
            this.state.touchCount = 0;
        }, 300);

        // 判断滑动距离和时间是否有效
        if (Math.abs(deltaY) > this.config.swipeThreshold && deltaTime < this.config.swipeTimeThreshold) {
            if (deltaY > 0) {
                // 向上滑动 - 下一个视频
                this.playRandomVideo();
            } else {
                // 向下滑动 - 上一个视频
                this.playPreviousVideo();
            }
        }
    }

    handleWheel(e) {
        e.preventDefault();

        // 获取当前时间和计算时间差
        const now = Date.now();
        const timeSinceLastScroll = now - this.state.lastScrollTime;
        const timeSinceLastSwitch = now - this.state.lastVideoSwitchTime;

        // 更新最后滚动时间
        this.state.lastScrollTime = now;

        // 如果正在滚落状态，重置滚落计时器
        if (this.state.isRolling) {
            // 清除之前的滚落计时器
            if (this.state.rollTimeout) {
                clearTimeout(this.state.rollTimeout);
            }

            // 重新设置滚落计时器
            this.state.rollTimeout = setTimeout(() => {
                this.state.isRolling = false;
                this.state.rollTimeout = null;
                // 滚落结束，播放最后一个视频
                if (e.deltaY > 0) {
                    this.playRandomVideo();
                } else {
                    this.playPreviousVideo();
                }
            }, this.config.rollDelay);

            return;
        }

        // 如果距离上次切换视频时间太短，进入滚落状态
        if (timeSinceLastSwitch < this.config.minSwitchInterval) {
            this.state.isRolling = true;

            // 设置滚落计时器
            this.state.rollTimeout = setTimeout(() => {
                this.state.isRolling = false;
                this.state.rollTimeout = null;
                // 滚落结束，播放最后一个视频
                if (e.deltaY > 0) {
                    this.playRandomVideo();
                } else {
                    this.playPreviousVideo();
                }
            }, this.config.rollDelay);

            return;
        }

        // 强化防抖机制：如果时间差小于防抖延迟，则取消之前的请求并设置新的请求
        if (timeSinceLastScroll < this.config.debounceDelay) {
            // 清除之前的待处理请求
            if (this.state.pendingVideoRequest) {
                clearTimeout(this.state.pendingVideoRequest);
            }

            // 设置新的待处理请求
            this.state.pendingVideoRequest = setTimeout(() => {
                // 更新最后切换时间
                this.state.lastVideoSwitchTime = Date.now();
                if (e.deltaY > 0) {
                    // 向下滚动 - 下一个视频
                    this.playRandomVideo();
                } else {
                    // 向上滚动 - 上一个视频
                    this.playPreviousVideo();
                }
                // 清除待处理请求引用
                this.state.pendingVideoRequest = null;
            }, this.config.debounceDelay);

            return;
        }

        // 正常处理滚动事件
        // 更新最后切换时间
        this.state.lastVideoSwitchTime = now;
        if (e.deltaY > 0) {
            // 向下滚动 - 下一个视频
            this.playRandomVideo();
        } else {
            // 向上滚动 - 上一个视频
            this.playPreviousVideo();
        }
    }

    handleKeyDown(e) {
        // 获取当前时间
        const now = Date.now();
        
        // 检查是否是快进快退按键
        if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
            e.preventDefault();
            
            // 显示进度条
            this.elements.progressContainer.classList.add('show');
            
            // 清除之前的隐藏定时器（如果存在）
            if (this.state.progressHideTimeout) {
                clearTimeout(this.state.progressHideTimeout);
            }
            
            // 设置新的隐藏定时器
            this.state.progressHideTimeout = setTimeout(() => {
                this.elements.progressContainer.classList.remove('show');
                this.state.progressHideTimeout = null;
            }, 1000); // 1秒后隐藏
            
            // 计算距离上次快进快退的时间差
            const timeDiff = now - this.state.lastSeekTime;
            
            // 如果在加速阈值内，则增加步长，否则重置步长
            if (timeDiff < this.config.seekAccelerationThreshold) {
                // 增加步长，但不超过最大值
                this.state.currentSeekStep = Math.min(
                    this.state.currentSeekStep + 1, 
                    this.config.maxSeekStep
                );
            } else {
                // 重置步长
                this.state.currentSeekStep = this.config.seekStep;
            }
            
            // 更新上次快进快退时间
            this.state.lastSeekTime = now;
            
            // 根据按键执行快进或快退
            if (e.key === 'ArrowLeft') {
                this.seekVideo(-this.state.currentSeekStep);
            } else {
                this.seekVideo(this.state.currentSeekStep);
            }
            
            // 更新进度条显示
            this.updateProgress();
            
            return;
        }
        
        // 处理其他按键
        switch (e.key) {
            case 'ArrowUp':
                e.preventDefault();
                this.playPreviousVideo();
                break;
            case 'ArrowDown':
                e.preventDefault();
                this.playRandomVideo();
                break;
            case ' ':
                e.preventDefault();
                this.togglePlay();
                break;
            case 'f':
            case 'F':
                e.preventDefault();
                this.toggleFullscreen();
                break;
            case 'r':
            case 'R':
                e.preventDefault();
                this.refreshVideoIndex();
                break;
            case 'm':
            case 'M':
                e.preventDefault();
                this.toggleMute();
                break;
            case 'h':
            case 'H':
                e.preventDefault();
                this.toggleKeyboardHint();
                break;
            case 'l':
            case 'L':
                e.preventDefault();
                this.togglePlayMode();
                break;
        }
    }

    togglePlay() {
        if (this.elements.currentVideo.paused) {
            this.elements.currentVideo.play().then(() => {
                // 使用淡出效果隐藏播放覆盖层
                this.elements.playOverlay.classList.remove('fade-in');
                this.elements.playOverlay.classList.add('fade-out');
                
                // 硡保动画完成后完全隐藏
                setTimeout(() => {
                    if (this.elements.currentVideo.paused === false) {
                        this.elements.playOverlay.classList.add('hidden');
                    }
                }, 300);
                
                this.elements.playIcon.className = 'fa fa-pause text-3xl text-white';
            }).catch(error => {
                console.error('播放失败:', error);
                this.showError('播放失败');
            });
        } else {
            this.elements.currentVideo.pause();
            // 使用淡入效果显示播放覆盖层
            this.elements.playOverlay.classList.remove('hidden', 'fade-out');
            this.elements.playOverlay.classList.add('fade-in');
            this.elements.playIcon.className = 'fa fa-play text-3xl text-white ml-1';
        }
    }

    toggleMute() {
        this.state.isMuted = !this.state.isMuted;
        this.elements.currentVideo.muted = this.state.isMuted;

        if (this.state.isMuted) {
            this.elements.muteIcon.className = 'fa fa-volume-off text-xl text-white';
        } else {
            this.elements.muteIcon.className = 'fa fa-volume-up text-xl text-white';
        }
    }

    /**
     * 切换键盘提示信息的显示/隐藏（同时控制播放模式显示和静音图标）
     */
    toggleKeyboardHint() {
        // 如果提示信息当前是隐藏的，则显示它、播放模式和静音图标
        if (this.elements.keyboardHint.classList.contains('hidden')) {
            this.elements.keyboardHint.classList.remove('hidden');
            this.elements.playModeIndicator.classList.remove('hidden');
            document.getElementById('muteControl').classList.remove('hidden');
        } else {
            // 如果提示信息当前是显示的，则隐藏它、播放模式和静音图标
            this.elements.keyboardHint.classList.add('hidden');
            this.elements.playModeIndicator.classList.add('hidden');
            document.getElementById('muteControl').classList.add('hidden');
        }
    }

    /**
     * 调整视频播放进度
     * @param {number} offset - 时间偏移量（秒），正数表示快进，负数表示快退
     */
    seekVideo(offset) {
        if (this.elements.currentVideo) {
            const newTime = this.elements.currentVideo.currentTime + offset;
            // 边界检查
            if (newTime >= 0 && newTime <= this.elements.currentVideo.duration) {
                this.elements.currentVideo.currentTime = newTime;
            }
        }
    }

    toggleFullscreen() {
        if (!document.fullscreenElement) {
            this.elements.videoContainer.requestFullscreen().catch(err => {
                console.error(`全屏错误: ${err.message}`);
                this.showError('全屏切换失败');
            });
        } else {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            }
        }
    }

    /**
     * 处理全屏变化事件
     */
    handleFullscreenChange() {
        if (document.fullscreenElement) {
            // 进入全屏模式
            this.elements.videoContainer.classList.add('fullscreen');
            // 在全屏模式下重置容器尺寸以适应屏幕
            this.elements.videoContainer.style.width = '';
            this.elements.videoContainer.style.height = '';
        } else {
            // 退出全屏模式
            this.elements.videoContainer.classList.remove('fullscreen');
            // 重新调整容器尺寸以适应视频
            this.adjustContainerForVideo();
        }
    }

    loadVideoWithTimeout(signal, maxRetries = 3) {
        return new Promise((resolve, reject) => {
            let retryCount = 0;

            const attemptLoad = () => {
                // 检查信号是否已中止
                if (signal && signal.aborted) {
                    reject(new Error('视频请求被中止'));
                    return;
                }

                const loadTimeout = setTimeout(() => {
                    handleLoadError(new Error('视频加载超时'));
                }, 15000);

                const loadedHandler = () => {
                    clearTimeout(loadTimeout);
                    // 移除事件监听器
                    this.elements.currentVideo.removeEventListener('loadeddata', loadedHandler);
                    this.elements.currentVideo.removeEventListener('error', errorHandler);
                    if (signal) {
                        signal.removeEventListener('abort', abortHandler);
                    }
                    resolve();
                };

                const errorHandler = (event) => {
                    clearTimeout(loadTimeout);
                    // 移除事件监听器
                    this.elements.currentVideo.removeEventListener('loadeddata', loadedHandler);
                    this.elements.currentVideo.removeEventListener('error', errorHandler);
                    if (signal) {
                        signal.removeEventListener('abort', abortHandler);
                    }
                    // 获取具体的错误信息
                    const error = event.target.error;
                    handleLoadError(new Error(`视频加载错误: ${error ? error.message : '未知错误'}`));
                };

                // 监听中止信号
                const abortHandler = () => {
                    clearTimeout(loadTimeout);
                    // 移除事件监听器
                    this.elements.currentVideo.removeEventListener('loadeddata', loadedHandler);
                    this.elements.currentVideo.removeEventListener('error', errorHandler);
                    if (signal) {
                        signal.removeEventListener('abort', abortHandler);
                    }
                    reject(new Error('视频请求被中止'));
                };

                const handleLoadError = (error) => {
                    console.log(`视频加载失败 (尝试 ${retryCount + 1}/${maxRetries + 1}):`, error.message);

                    // 如果还有重试次数且不是中止错误，则重试
                    if (retryCount < maxRetries && error.name !== 'AbortError' && !error.message.includes('视频请求被中止')) {
                        retryCount++;
                        console.log(`等待1秒后进行第 ${retryCount} 次重试...`);
                        setTimeout(() => {
                            // 重新尝试加载
                            attemptLoad();
                        }, 1000);
                    } else {
                        reject(error);
                    }
                };

                this.elements.currentVideo.addEventListener('loadeddata', loadedHandler, { once: true });
                this.elements.currentVideo.addEventListener('error', errorHandler, { once: true });

                // 如果提供了信号对象，监听中止事件
                if (signal) {
                    signal.addEventListener('abort', abortHandler, { once: true });
                }

                this.elements.currentVideo.load();
            };

            // 开始第一次加载尝试
            attemptLoad();
        });
    }

    /**
     * 清理之前的视频资源
     */
    cleanupPreviousVideo() {
        if (this.elements.currentVideo) {
            // 暂停当前视频
            this.elements.currentVideo.pause();
            
            // 清空视频源
            this.elements.currentVideo.src = '';
            
            // 移除所有事件监听器
            this.elements.currentVideo.onloadeddata = null;
            this.elements.currentVideo.onerror = null;
            this.elements.currentVideo.onwaiting = null;
            this.elements.currentVideo.onplaying = null;
            this.elements.currentVideo.onended = null;
            
            // 强制重新加载以清理资源
            this.elements.currentVideo.load();
        }
    }

    /**
     * 预加载下一个视频
     */
    prefetchNextVideo() {
        if (this.state.videoList.length <= 1) return;

        // 获取下一个随机视频索引
        const nextIndex = this.state.shuffledIndices[this.state.currentShuffledIndex];

        // 预加载下一个视频
        const nextVideo = this.state.videoList[nextIndex];
        if (nextVideo && nextVideo.url) {
            // 使用HTML5视频元素预加载视频
            const preloadVideo = document.createElement('video');
            preloadVideo.preload = 'auto'; // 自动预加载视频数据
            preloadVideo.src = nextVideo.url;
            
            // 存储预加载的视频元素以便清理
            this.state.preloadedVideos = this.state.preloadedVideos || [];
            this.state.preloadedVideos.push({
                index: nextIndex,
                element: preloadVideo
            });
            
            // 限制预加载视频数量，最多保留3个
            if (this.state.preloadedVideos.length > 3) {
                const removed = this.state.preloadedVideos.shift();
                // 移除预加载的视频元素
                if (removed.element) {
                    removed.element.removeAttribute('src');
                    removed.element.load(); // 重置视频元素
                }
            }
            
            console.log('预加载视频:', nextVideo.title);
        }
    }

    handleVideoError(event) {
        this.hideLoading();
        this.showError('视频播放失败', event);
    }

    /**
     * 根据视频分辨率和窗口尺寸调整容器尺寸
     */
    adjustContainerForVideo() {
        // 确保视频元素和元数据已加载
        if (!this.elements.currentVideo || !this.elements.currentVideo.videoWidth || !this.elements.currentVideo.videoHeight) {
            return;
        }

        const videoWidth = this.elements.currentVideo.videoWidth;
        const videoHeight = this.elements.currentVideo.videoHeight;
        
        // 计算视频宽高比
        const aspectRatio = videoWidth / videoHeight;
        
        // 获取窗口尺寸
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        
        // 直接使用窗口尺寸作为可用显示区域，确保容器能够完全填充屏幕
        const availableWidth = windowWidth;
        const availableHeight = windowHeight;
        
        // 计算基于视频比例的理想尺寸
        let maxWidth, maxHeight;
        
        // 根据视频方向选择主要约束维度
        if (aspectRatio > 1) {
            // 横屏视频 - 优先考虑宽度约束，尽可能占满可用宽度
            maxWidth = availableWidth;
            maxHeight = maxWidth / aspectRatio;
        } else if (aspectRatio < 1) {
            // 竖屏视频 - 优先考虑高度约束，尽可能占满可用高度
            maxHeight = availableHeight;
            maxWidth = maxHeight * aspectRatio;
        } else {
            // 正方形视频
            maxWidth = availableWidth;
            maxHeight = availableHeight;
        }
        
        // 确保容器尺寸不会超过窗口尺寸
        if (maxWidth > availableWidth) {
            maxWidth = availableWidth;
            maxHeight = maxWidth / aspectRatio;
        }
        
        if (maxHeight > availableHeight) {
            maxHeight = availableHeight;
            maxWidth = maxHeight * aspectRatio;
        }
        
        // 应用计算后的尺寸
        this.elements.videoContainer.style.width = `${maxWidth}px`;
        this.elements.videoContainer.style.height = `${maxHeight}px`;
        
        console.log(`窗口尺寸: ${windowWidth}x${windowHeight}, 视频分辨率: ${videoWidth}x${videoHeight}, 容器尺寸: ${maxWidth}x${maxHeight}`);
    }

    showLoading() {
        this.state.isLoading = true;
        // 使用批量更新来优化DOM操作
        this.batchUpdateClasses([
            { 
                element: this.elements.loadingIndicator, 
                add: ['fade-in'], 
                remove: ['hidden', 'fade-out'] 
            },
            { 
                element: this.elements.playOverlay, 
                add: ['fade-out'], 
                remove: ['fade-in'] 
            }
        ]);
        
        // 确保动画完成后完全隐藏
        setTimeout(() => {
            if (this.state.isLoading) {
                this.elements.playOverlay.classList.add('hidden');
            }
        }, 300);
    }

    hideLoading() {
        this.state.isLoading = false;
        // 使用批量更新来优化DOM操作
        this.batchUpdateClasses([
            { 
                element: this.elements.loadingIndicator, 
                add: ['fade-out'], 
                remove: ['fade-in'] 
            }
        ]);
        
        // 确保动画完成后完全隐藏
        setTimeout(() => {
            if (!this.state.isLoading) {
                this.elements.loadingIndicator.classList.add('hidden');
            }
        }, 300);
    }

    showError(message = '加载失败', error = null) {
        // 更新错误消息文本
        let errorMessage = message;
        if (error) {
            errorMessage += `\n详细信息: ${error.message}\n文件名: ${error.filename || '未知'}\n行号: ${error.lineno || '未知'}\n列号: ${error.colno || '未知'}`;
        }
        // 更新错误消息显示元素
        this.elements.errorMessage.querySelector('#errorText').textContent = errorMessage;
        
        // 使用淡入效果显示错误消息
        this.elements.errorMessage.classList.remove('hidden', 'fade-out');
        this.elements.errorMessage.classList.add('fade-in');
        
        // 隐藏加载指示器
        this.hideLoading();
        
        console.error('播放器错误:', errorMessage);
        if (error) {
            console.error('错误详情:', error);
        }
    }

    hideError() {
        // 使用淡出效果隐藏错误消息
        this.elements.errorMessage.classList.remove('fade-in');
        this.elements.errorMessage.classList.add('fade-out');
        
        // 确保动画完成后完全隐藏
        setTimeout(() => {
            this.elements.errorMessage.classList.add('hidden');
        }, 300);
    }

    showHistoryHint() {
        // 使用淡入效果显示历史提示
        this.elements.historyHint.classList.remove('hidden', 'fade-out');
        this.elements.historyHint.classList.add('fade-in');
        
        // 2秒后使用淡出效果隐藏提示
        setTimeout(() => {
            this.elements.historyHint.classList.remove('fade-in');
            this.elements.historyHint.classList.add('fade-out');
            
            // 确保动画完成后完全隐藏
            setTimeout(() => {
                this.elements.historyHint.classList.add('hidden');
            }, 300);
        }, 2000);
    }

    hideSwipeHint() {
        // 5秒后使用淡出效果隐藏滑动提示
        setTimeout(() => {
            // 使用淡出效果隐藏滑动提示
            this.elements.swipeHint.classList.remove('fade-in');
            this.elements.swipeHint.classList.add('fade-out');
            
            // 确保动画完成后完全隐藏
            setTimeout(() => {
                this.elements.swipeHint.classList.add('hidden');
            }, 300);
        }, 5000);
    }

    isMobile() {
        return /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
    }
    
    /**
     * 批量更新DOM元素的类名
     * @param {Array} updates - 包含元素和类名操作的数组
     * @example
     * this.batchUpdateClasses([
     *   { element: this.elements.loadingIndicator, add: ['fade-in'], remove: ['hidden', 'fade-out'] },
     *   { element: this.elements.playOverlay, add: ['fade-out'], remove: ['fade-in'] }
     * ]);
     */
    batchUpdateClasses(updates) {
        // 直接批量处理DOM类名更新
        updates.forEach(update => {
            const { element, add = [], remove = [] } = update;
            
            // 批量移除类名
            remove.forEach(className => element.classList.remove(className));
            
            // 批量添加类名
            add.forEach(className => element.classList.add(className));
        });
    }

    formatTime(seconds) {
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = Math.floor(seconds % 60);
        return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
    }

    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    /**
     * 更新进度条显示
     */
    updateProgress() {
        // 只在视频有持续时间时更新进度条宽度
        if (this.elements.currentVideo.duration) {
            const percent = (this.elements.currentVideo.currentTime / this.elements.currentVideo.duration) * 100;
            this.elements.progressBar.style.width = percent + '%';
        }
        
        // 不再自动显示进度条，只在拖拽或悬停时显示
    }

    /**
     * 处理进度条点击事件
     */
    handleProgressClick(e) {
        // 防止在拖拽时触发点击事件
        if (this.state.isDragging) return;
        
        const rect = this.elements.progressContainer.getBoundingClientRect();
        const pos = (e.clientX - rect.left) / rect.width;
        this.seekVideoToPosition(pos);
    }

    /**
     * 处理进度条拖拽开始
     */
    handleProgressDragStart(e) {
        e.preventDefault();
        this.state.isDragging = true;
        this.elements.progressContainer.classList.add('show', 'dragging');
        this.updateProgressByPosition(e.clientX);
    }

    /**
     * 处理进度条拖拽过程
     */
    handleProgressDrag(e) {
        if (this.state.isDragging) {
            e.preventDefault();
            this.updateProgressByPosition(e.clientX);
        }
    }

    /**
     * 处理进度条拖拽结束
     */
    handleProgressDragEnd(e) {
        if (this.state.isDragging) {
            this.state.isDragging = false;
            this.elements.progressContainer.classList.remove('dragging');
            this.updateProgressByPosition(e.clientX);
        }
    }

    /**
     * 处理移动端触摸开始
     */
    handleProgressTouchStart(e) {
        e.preventDefault();
        this.state.isDragging = true;
        this.elements.progressContainer.classList.add('show', 'dragging');
        this.updateProgressByPosition(e.touches[0].clientX);
    }

    /**
     * 处理移动端触摸移动
     */
    handleProgressTouchMove(e) {
        if (this.state.isDragging) {
            e.preventDefault();
            this.updateProgressByPosition(e.touches[0].clientX);
        }
    }

    /**
     * 处理移动端触摸结束
     */
    handleProgressTouchEnd(e) {
        if (this.state.isDragging) {
            this.state.isDragging = false;
            this.elements.progressContainer.classList.remove('dragging');
        }
    }

    /**
     * 根据位置更新视频进度
     */
    updateProgressByPosition(clientX) {
        const rect = this.elements.progressContainer.getBoundingClientRect();
        let pos = (clientX - rect.left) / rect.width;
        pos = Math.max(0, Math.min(1, pos)); // 限制在0-1之间
        this.seekVideoToPosition(pos);
    }

    /**
      * 跳转到指定位置
      */
     seekVideoToPosition(position) {
         if (this.elements.currentVideo.duration) {
             const newTime = position * this.elements.currentVideo.duration;
             // 边界检查
             if (newTime >= 0 && newTime <= this.elements.currentVideo.duration) {
                 this.elements.currentVideo.currentTime = newTime;
                 // 立即更新进度条显示
                 this.elements.progressBar.style.width = (position * 100) + '%';
             }
         }
     }
     /**
      * 切换播放模式
      */
     togglePlayMode() {
         // 切换播放模式
         this.state.playMode = this.state.playMode === 'random' ? 'loop' : 'random';
         
         // 更新UI显示
         const modeText = this.state.playMode === 'random' ? '随机播放' : '单视频循环';
         document.getElementById('modeText').textContent = modeText;
         
         console.log('播放模式已切换为:', modeText);
     }
 }

 /**
  * 初始化播放器
  */
 document.addEventListener('DOMContentLoaded', () => {
     try {
         // 创建播放器实例
         window.videoPlayer = new ShortVideoPlayer();

         // 暴露全局API
         window.refreshVideoIndex = () => window.videoPlayer.refreshVideoIndex();
         window.playRandomVideo = () => window.videoPlayer.playRandomVideo();
         window.toggleMute = () => window.videoPlayer.toggleMute();

         console.log('播放器初始化完成');
     } catch (error) {
         console.error('播放器初始化失败:', error);
         alert('播放器加载失败，请检查服务器连接');
     }
 });